home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
351-375
/
362
/
puzz
/
source
/
loadpic.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-14
|
5KB
|
252 lines
/* ILBM picture reader etc. for PUZZ M.J.Round January 1990
Largely copied from 'view.c' by D. John Hodgson.
*/
#define SR(a,b,c) if (Read(a,(char *)b,c)==-1L) return(NULL);
#define MAXWIDTH 376 /* max non-HIRES width */
#define MAXHEIGHT 242 /* max non-interlaced height (NTSC) */
#define MAXCOLORS 32 /* max # colors supported */
#define MakeID(a,b,c,d) ((a)<<24L | (b)<<16L | (c)<<8 | (d))
#define ID_FORM MakeID('F','O','R','M')
#define ID_ILBM MakeID('I','L','B','M')
#define ID_BMHD MakeID('B','M','H','D')
#define ID_CAMG MakeID('C','A','M','G')
#define ID_CMAP MakeID('C','M','A','P')
#define ID_BODY MakeID('B','O','D','Y')
typedef struct
{
long ckID,ckSize;
} Chunk;
Chunk header;
char *bufstart;
struct BitMap b;
struct RastPort rp;
struct RastPort dbuffrastport;
struct BitMap dbuffbitmap;
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern BitMapHeader bmhd;
extern struct TextAttr MyFont;
struct Screen *ReadILBM(BPTR fp)
{
struct NewScreen NewScreen;
struct Screen *screen;
char colormap[MAXCOLORS][3],*sourcebuf;
short colorcount;
long id,ViewModes=0;
SR(fp,&header,(long)sizeof(header));
if (header.ckID!=ID_FORM) return(NULL);
SR(fp,&id,(long)sizeof(id));
if (id!=ID_ILBM) return(NULL);
for (;;)
{
SR(fp,&header,(long)sizeof(header));
if (header.ckID==ID_BODY) break;
switch(header.ckID)
{
case ID_BMHD:
SR(fp,&bmhd,(long)sizeof(bmhd));
break;
case ID_CMAP:
SR(fp,&colormap[0][0],(long)header.ckSize);
colorcount=header.ckSize/3;
break;
case ID_CAMG:
SR(fp,&ViewModes,(long)header.ckSize);
break;
default:
Seek(fp,(((header.ckSize)+1)&(~1L)),OFFSET_CURRENT);
}
}
/* Read planes into RAM for ease of decompression */
sourcebuf=bufstart=AllocMem((long)header.ckSize,MEMF_PUBLIC);
if (sourcebuf==0L) return (NULL);
SR(fp,sourcebuf,(long)header.ckSize);
NewScreen.LeftEdge=0; NewScreen.TopEdge=0;
NewScreen.Width=bmhd.w; NewScreen.Height=bmhd.h;
NewScreen.Depth=bmhd.nPlanes;
/* make some forced assumptions if CAMG chunk unavailable */
if (!(NewScreen.ViewModes=ViewModes))
{
if (bmhd.w>MAXWIDTH) NewScreen.ViewModes|=HIRES;
if (bmhd.h>MAXHEIGHT) NewScreen.ViewModes|=LACE;
}
NewScreen.Type=CUSTOMSCREEN;
NewScreen.Font=&MyFont;
NewScreen.Gadgets=0L;
screen=OpenScreen(&NewScreen);
while (colorcount--)
SetRGB4
(
&screen->ViewPort,
(long)colorcount,
colormap[colorcount][0]>>4L,colormap[colorcount][1]>>4L,
colormap[colorcount][2]>>4L
);
return(screen);
}
void Expand(screen,bmhd) /* Fast line decompress/deinterleave */
struct Screen *screen;
BitMapHeader *bmhd;
{
register char *sourcebuf;
register char n,*destbuf; /* in order of preferred allocation */
register short plane,linelen,rowbytes,i;
sourcebuf = bufstart;
linelen=bmhd->w/8;
for (i=0;i<bmhd->h;i++) /* process n lines/screen */
{
for (plane=0;plane<bmhd->nPlanes;plane++)
{ /* process n planes/line */
destbuf=(char *)(screen->BitMap.Planes[plane])+linelen*i;
if (bmhd->compression== 1)
{ /* compressed screen? */
rowbytes=linelen;
while (rowbytes)
{ /* unpack until 1 scan-line complete */
n=*sourcebuf++; /* fetch block run marker */
/* uncompressed block? copy n bytes verbatim */
if (n>=0)
{
movmem
(
sourcebuf,
destbuf,
(unsigned int)++n
);
rowbytes-=n;
destbuf+=n;
sourcebuf+=n;
}
else
{ /* compr. block? expand n duplicate bytes */
n=-n+1;
rowbytes-=n;
setmem
(
destbuf,
(unsigned int)n,
(unsigned int)*sourcebuf++
);
destbuf+=n;
}
} /* finish unpacking line */
}
else
{ /* uncompressed? just copy */
movmem(sourcebuf,destbuf,(unsigned int)linelen);
sourcebuf+=linelen;
}
} /* finish interleaved planes, lines */
}
}
struct RastPort *getbuffs(int width,int height)
{
int i;
InitBitMap(&b,bmhd.nPlanes,bmhd.w,11);
for (i=0; i<bmhd.nPlanes; i++)
{
b.Planes[i] = (PLANEPTR)AllocRaster(bmhd.w,11);
if(b.Planes[i] == NULL)
{
while (--i >= 0)
FreeRaster(b.Planes[i],bmhd.w,11);
return (NULL);
}
}
InitRastPort(&rp);
rp.BitMap = &b;
InitBitMap(&dbuffbitmap,bmhd.nPlanes,width,height);
for (i=0; i<bmhd.nPlanes; i++)
{
dbuffbitmap.Planes[i] = (PLANEPTR)AllocRaster(width,height);
if(dbuffbitmap.Planes[i] == NULL)
{
while (--i >= 0)
FreeRaster(dbuffbitmap.Planes[i],width,height);
return (NULL);
}
}
InitRastPort(&dbuffrastport);
dbuffrastport.BitMap = &dbuffbitmap;
return (&dbuffrastport);
}
void saveundermenu(struct RastPort *rast)
{
ClipBlit
(
rast,0,0 /* source posn */
,&rp,0,0 /* dest posn */
,bmhd.w,11 /* size */
,0xc0 /* direct copy */
);
}
void drawovermenu(struct RastPort *rast)
{
ClipBlit
(
&rp,0,0 /* source posn */
,rast,0,0 /* dest posn */
,bmhd.w,11 /* size */
,0xc0 /* direct copy */
);
}
void freebuffs(int width,int height)
{
int i;
for (i=0; i<bmhd.nPlanes; i++)
FreeRaster(dbuffbitmap.Planes[i],width,height);
for (i=0; i<bmhd.nPlanes; i++)
FreeRaster(b.Planes[i],bmhd.w,11);
FreeMem(bufstart,(long)header.ckSize); /* free compressed buffer */
}